#ifndef HDCAMERARENDERER_H
#define HDCAMERARENDERER_H

#include <GL\GLee.h>
#include <QGLWidget>
#include <QMutex>
#include "cv.h"
#include "highgui.h"
#include <ctype.h>
#include <QtGui>
#include <qdatetime.h>
#include "hdobject.h"

class TrackerGLThread;

#include <windows.h>
#include <Cg\cg.h>										// Cg Header
#include <Cg\cggl.h>									// Cg OpenGL Specific Header

#pragma comment( lib, "cg.lib" )						// Search For Cg.lib While Linking
#pragma comment( lib, "cggl.lib" )						// Search For CgGL.lib While Linking

enum HDDemoID
{
	DEMO_NONE = -1,
	DEMO_MOUSE = 0,
	DEMO_IMAGE = 1,
	DEMO_IMAGE3 = 2
};
// #define DEMO_NONE -1
// #define DEMO_MOUSE 0
// #define DEMO_IMAGE 1
// #define DEMO_IMAGE3 2

class HDCameraRenderer : public QGLWidget
{
	Q_OBJECT

protected:
	void initializeGL();
	void paintGL();
	void resizeGL(int width, int height);
	void keyPressEvent(QKeyEvent *event);
	void keyReleaseEvent(QKeyEvent * event);
	void mousePressEvent(QMouseEvent *event);
	void mouseReleaseEvent(QMouseEvent *event);
	void mouseMoveEvent(QMouseEvent *event);

public:
	HDCameraRenderer(QWidget *parent = 0, int cameraIndex = 0);
	~HDCameraRenderer();
	void setFrame(uchar* data, int width, int height);
	void updateHistogramPanels();
	QSize sizeHint();

	bool backProjection();
	void setBackProjection(bool enable);

	HDDemoID demoID();
	void setDemoID(HDDemoID id);

	void addMarker();
	HDObject* selectedMarker(); 

	QList<HDObject*>	objectMarkers;
	
public slots:
	void changeFrame(IplImage* frame);

signals:
	void selectionCompleted(HDCameraRenderer* sender);
	void focusChanged(int index);

private:
	bool initCG();
	bool initTextures();

	void render();

	void updateHistogram();
	void saveGLState();
	void restoreGLState();
	void setupCGParameters(int index);
	void trackMarkers();
	void renderToTexture(GLuint sourceTexture, QRect srcRect,
		GLuint distTexture, QRect distRect, 
		GLuint frameBufferObject, CGpass pass);
	void renderToScreen(GLuint sourceTexture, QRect srcRect,
		GLuint distTexture, QRect distRect);
	void drawForeground();

	void drawText( QPainter * painter );
	void drawObjectsCursor( QPainter * painter );
	void startDemo( QPainter *painter );
	void startMouseDemo();
	void startImage2DDemo( QPainter *painter );
	void startImage3DDemo( QPainter *painter );

	float gaussian(float amplitude, float mean, float sigma, float x);

	void generateMarkerCursor();

	bool _backProjection;
	HDDemoID _demoID;

	float minHue;
	float maxHue;
	float minSaturation;
	float maxSaturation;
	float minValue;
	float maxValue;

	GLuint	texture;
	bool rubberBandIsShown;
	bool bMouseDown;
	QPoint pntA, pntB;
	QRect rctSelection;
	int frameWidth;
	int frameHeight;
	QMutex mutex;
	int markerRadius;


	int hdims;
	int sdims;
	int vdims;

	QPixmap pmMarkerCursor;

	bool bLoading;

	/************************************************************************/
	/* CG Stuff																*/
	/************************************************************************/
	CGcontext	cgContext;				// A Context To Hold Our Cg Program(s)

	CGeffect	cgEffect;
	CGtechnique cgTechnique;
	CGpass		cgPass;

	CGparameter	objectID, objectsCount, centroid, radius;
	CGparameter origSampler, modSampler;
	CGparameter hueHistSampler, satHistSampler, valHistSampler;

	GLuint fbo;
	GLuint textureSmooth;
	GLuint offscreenTexture2, offscreenTexture3, offscreenTexture4;
	GLuint offscreenTexture5, offscreenTexture6;

	int counter;
	QTime fpsTime;
	long timeElapsed;

	QTimer *updateTimer;
	QImage img;
	float searchRadius;
	
	IplImage *_srcImage;
	QDesktopWidget *desktopWid;
	int desktopWidth, desktopHeight;

	bool once;
	int _cameraIndex;
	int markersCount;
	int camerasCount;
	GLfloat scaleX, scaleY;

	GLfloat pixels[4*640*480];
};

#endif // HDCAMERARENDERER_H
